package db

import (
	"GoIris/filechain"
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"time"
)

func ConnectDB() (DB *sql.DB, err error) {
	dsn := fmt.Sprintf("%s:%s@%s(%s:%d)/%s", USERNAME, PASSWORD, NETWORK, SERVER, PORT, DATABASE)
	DB, err = sql.Open("mysql", dsn)
	if err != nil {

		return nil, err
	}
	DB.SetConnMaxLifetime(100 * time.Second)
	DB.SetMaxOpenConns(100)
	DB.SetMaxIdleConns(16)
	return DB, err

}

const (
	USERNAME = "root"
	PASSWORD = "qwer123"
	NETWORK  = "tcp"
	SERVER   = "localhost"
	PORT     = 3306
	DATABASE = "goiris"
)

type User struct {
	email        string `db:"email"`
	password     string `db:"password"`
	index        int    `db:"index"`
	content      string `db:content`
	ID           int    `db:ID`
	Timestamp    string `db:Timestamp`
	PreviousHash string `db:PreviousHash`
}

//注册用户
func (U *User) InsertUser(DB *sql.DB, email string, password string) {
	_, err := DB.Exec("insert INTO users(email,password) values(?,?)", email, password)
	if err != nil {
		fmt.Printf("Insert failed,err:%v", err)
		return
	}
	//fmt.Println("插入成功~")
	//DB.Close()
}

//存入区块
func (U *User) InsertBlock(DB *sql.DB, ID int, email string, Times string, Pre string, content string) {
	_, err := DB.Exec("insert INTO blocks(ID,email,Timestamp,PreviousHash,content) values(?,?,?,?,?)", ID, email, Times, Pre, content)
	if err != nil {
		fmt.Printf("Insert failed,err:%v", err)
		return
	}
	fmt.Println("插入成功~")
}

//查询用户
func (U *User) QueryOne(DB *sql.DB, email string) (PassWord string) {

	row := DB.QueryRow("select * from users where email=? ", fmt.Sprintf("%s", email))
	if err := row.Scan(&U.email, &U.password); err != nil {
		fmt.Printf("scan failed, err:%v", err)
		return "密码错误"
	}
	//fmt.Println(U.password)
	return U.password
}

//取出用户选择的特定区块
func (U *User) QueryContent(DB *sql.DB, index string) (content string) {
	row := DB.QueryRow("select * from blocks where ID = ? ", index)
	if err := row.Scan(&U.ID, &U.email, &U.Timestamp, &U.PreviousHash, &U.content); err != nil {
		fmt.Printf("scan failed , err : %v \n", err)
		return "查询内容不存在~"
	}
	return U.content
}

//取出头Block
func (U *User) QueryBlock(DB *sql.DB) (ID int, content []string) {
	// ID   := DB.QueryRow("select MAX(ID) from blocks")
	rows := DB.QueryRow("select * from blocks where ID = (select Max(ID) from blocks)")
	if err := rows.Scan(&U.ID, &U.email, &U.Timestamp, &U.PreviousHash, &U.content); err != nil {
		fmt.Println(err)
		return 0, nil
	}
	fmt.Println(U.ID)
	contents := map[string]interface{}{
		U.email: U.content,
	}
	fmt.Println("----------->数据库src构造<------------- \n", contents)
	btc := filechain.BlockBuild()
	_, block := btc.CreateBlock(U.ID, U.Timestamp, U.PreviousHash, contents)
	return U.ID, block
}

//取出单用户的所有数据
func (U *User) QueryUserDate(DB *sql.DB, email string) map[int]map[string]string {
	TempMapO := make(map[int]map[string]string)
	i := 0

	//查询多行
	rows, err := DB.Query("select * from blocks where email = ?", email)
	defer func() {
		if rows != nil {
			rows.Close() //可以关闭掉未scan连接一直占用
		}
	}()
	if err != nil {
		fmt.Println("---> error", err)
	}
	for rows.Next() {
		TempMapI := make(map[string]string)
		err = rows.Scan(&U.ID, &U.email, &U.Timestamp, &U.PreviousHash, &U.content)
		if err != nil {
			fmt.Println("---> error", err)
		}
		TempMapI["ID"] = fmt.Sprintf("%d", U.ID)
		TempMapI["content"] = U.content
		TempMapI["PreviousHash"] = U.PreviousHash
		TempMapI["Timestamp"] = U.Timestamp
		TempMapO[i] = TempMapI
		//fmt.Printf("%d   %s   %s    %s  \n",U.ID,U.content,U.PreviousHash,U.Timestamp)
		TempMapI = nil
		i++
	}
	return TempMapO
}

//创建数据库对象
func NewUser() *User {
	return new(User)
}

func mainx() {
	DB, err := ConnectDB()
	user := NewUser()
	if err != nil {
		fmt.Printf("Open mysql failed,err:%v\n", err)
	}
	//_,datas := user.QueryBlock(DB)
	//fmt.Printf("--->\n %s \n<---\n",datas)
	//json :=user.QueryUserDate(DB,"328047108@qq.com")
	//fmt.Println(json)
	content := user.QueryContent(DB, "7")
	fmt.Println(content)
}
